home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Utilities / BasiliskII / src / audio.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-02  |  17.0 KB  |  598 lines

  1. /*
  2.  *  audio.cpp - Audio support
  3.  *
  4.  *  Basilisk II (C) 1997-2001 Christian Bauer
  5.  *  Portions (C) 1997-1999 Marc Hellwig
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20.  */
  21.  
  22. /*
  23.  *  SEE ALSO
  24.  *    Inside Macintosh: Sound, chapter 5 "Sound Components"
  25.  */
  26.  
  27. #include "sysdeps.h"
  28. #include "cpu_emulation.h"
  29. #include "macos_util.h"
  30. #include "emul_op.h"
  31. #include "main.h"
  32. #include "audio.h"
  33. #include "audio_defs.h"
  34.  
  35. #define DEBUG 0
  36. #include "debug.h"
  37.  
  38.  
  39. // Global variables
  40. struct audio_status AudioStatus;    // Current audio status (sample rate etc.)
  41. bool audio_open = false;            // Flag: audio is initialized and ready
  42. int audio_frames_per_block;            // Number of audio frames per block
  43. uint32 audio_component_flags;        // Component feature flags
  44. uint32 audio_data = 0;                // Mac address of global data area
  45. static int open_count = 0;            // Open/close nesting count
  46.  
  47. bool AudioAvailable = false;        // Flag: audio output available (from the software point of view)
  48.  
  49.  
  50. /*
  51.  *  Reset audio emulation
  52.  */
  53.  
  54. void AudioReset(void)
  55. {
  56.     audio_data = 0;
  57. }
  58.  
  59.  
  60. /*
  61.  *  Get audio info
  62.  */
  63.  
  64. static int32 AudioGetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
  65. {
  66.     D(bug(" AudioGetInfo %c%c%c%c, infoPtr %08lx, source ID %08lx\n", selector >> 24, (selector >> 16) & 0xff, (selector >> 8) & 0xff, selector & 0xff, infoPtr, sourceID));
  67.     M68kRegisters r;
  68.     int i;
  69.  
  70.     switch (selector) {
  71.         case siSampleSize:
  72.             WriteMacInt16(infoPtr, AudioStatus.sample_size);
  73.             break;
  74.  
  75.         case siSampleSizeAvailable: {
  76.             r.d[0] = audio_num_sample_sizes * 2;
  77.             Execute68kTrap(0xa122, &r);    // NewHandle()
  78.             uint32 h = r.a[0];
  79.             if (h == 0)
  80.                 return memFullErr;
  81.             WriteMacInt16(infoPtr + sil_count, audio_num_sample_sizes);
  82.             WriteMacInt32(infoPtr + sil_infoHandle, h);
  83.             uint32 sp = ReadMacInt32(h);
  84.             for (i=0; i<audio_num_sample_sizes; i++)
  85.                 WriteMacInt16(sp + i*2, audio_sample_sizes[i]);
  86.             break;
  87.         }
  88.  
  89.         case siNumberChannels:
  90.             WriteMacInt16(infoPtr, AudioStatus.channels);
  91.             break;
  92.  
  93.         case siChannelAvailable: {
  94.             r.d[0] = audio_num_channel_counts * 2;
  95.             Execute68kTrap(0xa122, &r);    // NewHandle()
  96.             uint32 h = r.a[0];
  97.             if (h == 0)
  98.                 return memFullErr;
  99.             WriteMacInt16(infoPtr + sil_count, audio_num_channel_counts);
  100.             WriteMacInt32(infoPtr + sil_infoHandle, h);
  101.             uint32 sp = ReadMacInt32(h);
  102.             for (i=0; i<audio_num_channel_counts; i++)
  103.                 WriteMacInt16(sp + i*2, audio_channel_counts[i]);
  104.             break;
  105.         }
  106.  
  107.         case siSampleRate:
  108.             WriteMacInt32(infoPtr, AudioStatus.sample_rate);
  109.             break;
  110.  
  111.         case siSampleRateAvailable: {
  112.             r.d[0] = audio_num_sample_rates * 4;
  113.             Execute68kTrap(0xa122, &r);    // NewHandle()
  114.             uint32 h = r.a[0];
  115.             if (h == 0)
  116.                 return memFullErr;
  117.             WriteMacInt16(infoPtr + sil_count, audio_num_sample_rates);
  118.             WriteMacInt32(infoPtr + sil_infoHandle, h);
  119.             uint32 lp = ReadMacInt32(h);
  120.             for (i=0; i<audio_num_sample_rates; i++)
  121.                 WriteMacInt32(lp + i*4, audio_sample_rates[i]);
  122.             break;
  123.         }
  124.  
  125.         case siSpeakerMute:
  126.             WriteMacInt16(infoPtr, audio_get_speaker_mute());
  127.             break;
  128.  
  129.         case siSpeakerVolume:
  130.             WriteMacInt32(infoPtr, audio_get_speaker_volume());
  131.             break;
  132.  
  133.         case siHeadphoneMute:
  134.             WriteMacInt16(infoPtr, 0);
  135.             break;
  136.  
  137.         case siHeadphoneVolume:
  138.             WriteMacInt32(infoPtr, 0x01000100);
  139.             break;
  140.  
  141.         case siHeadphoneVolumeSteps:
  142.             WriteMacInt16(infoPtr, 13);
  143.             break;
  144.  
  145.         case siHardwareMute:
  146.             WriteMacInt16(infoPtr, audio_get_main_mute());
  147.             break;
  148.  
  149.         case siHardwareVolume:
  150.             WriteMacInt32(infoPtr, audio_get_main_volume());
  151.             break;
  152.  
  153.         case siHardwareVolumeSteps:
  154.             WriteMacInt16(infoPtr, 13);
  155.             break;
  156.  
  157.         case siHardwareBusy:
  158.             WriteMacInt16(infoPtr, AudioStatus.num_sources != 0);
  159.             break;
  160.  
  161.         default:    // Delegate to Apple Mixer
  162.             if (AudioStatus.mixer == 0)
  163.                 return badComponentSelector;
  164.             M68kRegisters r;
  165.             r.a[0] = infoPtr;
  166.             r.d[0] = selector;
  167.             r.a[1] = sourceID;
  168.             r.a[2] = AudioStatus.mixer;
  169.             Execute68k(audio_data + adatGetInfo, &r);
  170.             D(bug("  delegated to Apple Mixer, returns %08lx\n", r.d[0]));
  171.             return r.d[0];
  172.     }
  173.     return noErr;
  174. }
  175.  
  176.  
  177. /*
  178.  *  Set audio info
  179.  */
  180.  
  181. static int32 AudioSetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
  182. {
  183.     D(bug(" AudioSetInfo %c%c%c%c, infoPtr %08lx, source ID %08lx\n", selector >> 24, (selector >> 16) & 0xff, (selector >> 8) & 0xff, selector & 0xff, infoPtr, sourceID));
  184.     M68kRegisters r;
  185.     int i;
  186.  
  187.     switch (selector) {
  188.         case siSampleSize:
  189.             D(bug("  set sample size %08lx\n", infoPtr));
  190.             if (AudioStatus.num_sources)
  191.                 return siDeviceBusyErr;
  192.             for (i=0; i<audio_num_sample_sizes; i++)
  193.                 if (audio_sample_sizes[i] == infoPtr) {
  194.                     audio_set_sample_size(i);
  195.                     return noErr;
  196.                 }
  197.             return siInvalidSampleSize;
  198.  
  199.         case siSampleRate:
  200.             D(bug("  set sample rate %08lx\n", infoPtr));
  201.             if (AudioStatus.num_sources)
  202.                 return siDeviceBusyErr;
  203.             for (i=0; i<audio_num_sample_rates; i++)
  204.                 if (audio_sample_rates[i] == infoPtr) {
  205.                     audio_set_sample_rate(i);
  206.                     return noErr;
  207.                 }
  208.             return siInvalidSampleRate;
  209.  
  210.         case siNumberChannels:
  211.             D(bug("  set number of channels %08lx\n", infoPtr));
  212.             if (AudioStatus.num_sources)
  213.                 return siDeviceBusyErr;
  214.             for (i=0; i<audio_num_channel_counts; i++)
  215.                 if (audio_channel_counts[i] == infoPtr) {
  216.                     audio_set_channels(i);
  217.                     return noErr;
  218.                 }
  219.             return badChannel;
  220.  
  221.         case siSpeakerMute:
  222.             audio_set_speaker_mute((uint16)infoPtr);
  223.             break;
  224.  
  225.         case siSpeakerVolume:
  226.             D(bug("  set speaker volume %08lx\n", infoPtr));
  227.             audio_set_speaker_volume(infoPtr);
  228.             break;
  229.  
  230.         case siHeadphoneMute:
  231.         case siHeadphoneVolume:
  232.             break;
  233.  
  234.         case siHardwareMute:
  235.             audio_set_main_mute((uint16)infoPtr);
  236.             break;
  237.  
  238.         case siHardwareVolume:
  239.             D(bug("  set hardware volume %08lx\n", infoPtr));
  240.             audio_set_main_volume(infoPtr);
  241.             break;
  242.  
  243.         default:    // Delegate to Apple Mixer
  244.             if (AudioStatus.mixer == 0)
  245.                 return badComponentSelector;
  246.             r.a[0] = infoPtr;
  247.             r.d[0] = selector;
  248.             r.a[1] = sourceID;
  249.             r.a[2] = AudioStatus.mixer;
  250.             Execute68k(audio_data + adatSetInfo, &r);
  251.             D(bug("  delegated to Apple Mixer, returns %08lx\n", r.d[0]));
  252.             return r.d[0];
  253.     }
  254.     return noErr;
  255. }
  256.  
  257.  
  258. /*
  259.  *  Sound output component dispatch
  260.  */
  261.  
  262. int32 AudioDispatch(uint32 params, uint32 globals)
  263. {
  264.     D(bug("AudioDispatch params %08lx (size %d), what %d\n", params, ReadMacInt8(params + cp_paramSize), (int16)ReadMacInt16(params + cp_what)));
  265.     M68kRegisters r;
  266.     uint32 p = params + cp_params;
  267.  
  268.     switch ((int16)ReadMacInt16(params + cp_what)) {
  269.         // Basic component functions
  270.         case kComponentOpenSelect:
  271.             if (audio_data == 0) {
  272.  
  273.                 // Allocate global data area
  274.                 r.d[0] = SIZEOF_adat;
  275.                 Execute68kTrap(0xa71e, &r);    // NewPtrSysClear()
  276.                 if (r.a[0] == 0)
  277.                     return memFullErr;
  278.                 audio_data = r.a[0];
  279.                 D(bug(" global data at %08lx\n", audio_data));
  280.  
  281.                 // Put in 68k routines
  282.                 int p = audio_data + adatDelegateCall;
  283.                 WriteMacInt16(p, 0x598f); p += 2;    // subq.l    #4,sp
  284.                 WriteMacInt16(p, 0x2f09); p += 2;    // move.l    a1,-(sp)
  285.                 WriteMacInt16(p, 0x2f08); p += 2;    // move.l    a0,-(sp)
  286.                 WriteMacInt16(p, 0x7024); p += 2;    // moveq    #$24,d0
  287.                 WriteMacInt16(p, 0xa82a); p += 2;    // ComponentDispatch
  288.                 WriteMacInt16(p, 0x201f); p += 2;    // move.l    (sp)+,d0
  289.                 WriteMacInt16(p, M68K_RTS); p += 2;    // rts
  290.                 if (p - audio_data != adatOpenMixer)
  291.                     goto adat_error;
  292.                 WriteMacInt16(p, 0x558f); p += 2;    // subq.l    #2,sp
  293.                 WriteMacInt16(p, 0x2f09); p += 2;    // move.l    a1,-(sp)
  294.                 WriteMacInt16(p, 0x2f00); p += 2;    // move.l    d0,-(sp)
  295.                 WriteMacInt16(p, 0x2f08); p += 2;    // move.l    a0,-(sp)
  296.                 WriteMacInt16(p, 0x203c); p += 2;    // move.l    #$06140018,d0
  297.                 WriteMacInt32(p, 0x06140018); p+= 4;
  298.                 WriteMacInt16(p, 0xa800); p += 2;    // SoundDispatch
  299.                 WriteMacInt16(p, 0x301f); p += 2;    // move.w    (sp)+,d0
  300.                 WriteMacInt16(p, 0x48c0); p += 2;    // ext.l    d0
  301.                 WriteMacInt16(p, M68K_RTS); p += 2;    // rts
  302.                 if (p - audio_data != adatCloseMixer)
  303.                     goto adat_error;
  304.                 WriteMacInt16(p, 0x558f); p += 2;    // subq.l    #2,sp
  305.                 WriteMacInt16(p, 0x2f08); p += 2;    // move.l    a0,-(sp)
  306.                 WriteMacInt16(p, 0x203c); p += 2;    // move.l    #$02180018,d0
  307.                 WriteMacInt32(p, 0x02180018); p+= 4;
  308.                 WriteMacInt16(p, 0xa800); p += 2;    // SoundDispatch
  309.                 WriteMacInt16(p, 0x301f); p += 2;    // move.w    (sp)+,d0
  310.                 WriteMacInt16(p, 0x48c0); p += 2;    // ext.l    d0
  311.                 WriteMacInt16(p, M68K_RTS); p += 2;    // rts
  312.                 if (p - audio_data != adatGetInfo)
  313.                     goto adat_error;
  314.                 WriteMacInt16(p, 0x598f); p += 2;    // subq.l    #4,sp
  315.                 WriteMacInt16(p, 0x2f0a); p += 2;    // move.l    a2,-(sp)
  316.                 WriteMacInt16(p, 0x2f09); p += 2;    // move.l    a1,-(sp)
  317.                 WriteMacInt16(p, 0x2f00); p += 2;    // move.l    d0,-(sp)
  318.                 WriteMacInt16(p, 0x2f08); p += 2;    // move.l    a0,-(sp)
  319.                 WriteMacInt16(p, 0x2f3c); p += 2;    // move.l    #$000c0103,-(sp)
  320.                 WriteMacInt32(p, 0x000c0103); p+= 4;
  321.                 WriteMacInt16(p, 0x7000); p += 2;    // moveq    #0,d0
  322.                 WriteMacInt16(p, 0xa82a); p += 2;    // ComponentDispatch
  323.                 WriteMacInt16(p, 0x201f); p += 2;    // move.l    (sp)+,d0
  324.                 WriteMacInt16(p, M68K_RTS); p += 2;    // rts
  325.                 if (p - audio_data != adatSetInfo)
  326.                     goto adat_error;
  327.                 WriteMacInt16(p, 0x598f); p += 2;    // subq.l    #4,sp
  328.                 WriteMacInt16(p, 0x2f0a); p += 2;    // move.l    a2,-(sp)
  329.                 WriteMacInt16(p, 0x2f09); p += 2;    // move.l    a1,-(sp)
  330.                 WriteMacInt16(p, 0x2f00); p += 2;    // move.l    d0,-(sp)
  331.                 WriteMacInt16(p, 0x2f08); p += 2;    // move.l    a0,-(sp)
  332.                 WriteMacInt16(p, 0x2f3c); p += 2;    // move.l    #$000c0104,-(sp)
  333.                 WriteMacInt32(p, 0x000c0104); p+= 4;
  334.                 WriteMacInt16(p, 0x7000); p += 2;    // moveq    #0,d0
  335.                 WriteMacInt16(p, 0xa82a); p += 2;    // ComponentDispatch
  336.                 WriteMacInt16(p, 0x201f); p += 2;    // move.l    (sp)+,d0
  337.                 WriteMacInt16(p, M68K_RTS); p += 2;    // rts
  338.                 if (p - audio_data != adatPlaySourceBuffer)
  339.                     goto adat_error;
  340.                 WriteMacInt16(p, 0x598f); p += 2;    // subq.l    #4,sp
  341.                 WriteMacInt16(p, 0x2f0a); p += 2;    // move.l    a2,-(sp)
  342.                 WriteMacInt16(p, 0x2f09); p += 2;    // move.l    a1,-(sp)
  343.                 WriteMacInt16(p, 0x2f08); p += 2;    // move.l    a0,-(sp)
  344.                 WriteMacInt16(p, 0x2f00); p += 2;    // move.l    d0,-(sp)
  345.                 WriteMacInt16(p, 0x2f3c); p += 2;    // move.l    #$000c0108,-(sp)
  346.                 WriteMacInt32(p, 0x000c0108); p+= 4;
  347.                 WriteMacInt16(p, 0x7000); p += 2;    // moveq    #0,d0
  348.                 WriteMacInt16(p, 0xa82a); p += 2;    // ComponentDispatch
  349.                 WriteMacInt16(p, 0x201f); p += 2;    // move.l    (sp)+,d0
  350.                 WriteMacInt16(p, M68K_RTS); p += 2;    // rts
  351.                 if (p - audio_data != adatGetSourceData)
  352.                     goto adat_error;
  353.                 WriteMacInt16(p, 0x598f); p += 2;    // subq.l    #4,sp
  354.                 WriteMacInt16(p, 0x2f09); p += 2;    // move.l    a1,-(sp)
  355.                 WriteMacInt16(p, 0x2f08); p += 2;    // move.l    a0,-(sp)
  356.                 WriteMacInt16(p, 0x2f3c); p += 2;    // move.l    #$00040004,-(sp)
  357.                 WriteMacInt32(p, 0x00040004); p+= 4;
  358.                 WriteMacInt16(p, 0x7000); p += 2;    // moveq    #0,d0
  359.                 WriteMacInt16(p, 0xa82a); p += 2;    // ComponentDispatch
  360.                 WriteMacInt16(p, 0x201f); p += 2;    // move.l    (sp)+,d0
  361.                 WriteMacInt16(p, M68K_RTS); p += 2;    // rts
  362.                 if (p - audio_data != adatData)
  363.                     goto adat_error;
  364.             }
  365.             AudioAvailable = true;
  366.             if (open_count == 0)
  367.                 audio_enter_stream();
  368.             open_count++;
  369.             return noErr;
  370.  
  371. adat_error:    printf("FATAL: audio component data block initialization error\n");
  372.             QuitEmulator();
  373.             return openErr;
  374.  
  375.         case kComponentCanDoSelect:
  376.         case kComponentRegisterSelect:
  377.             return noErr;
  378.  
  379.         case kComponentVersionSelect:
  380.             return 0x00010003;
  381.  
  382.         case kComponentCloseSelect:
  383.             open_count--;
  384.             if (open_count == 0) {
  385.                 if (AudioStatus.mixer) {
  386.                     // Close Apple Mixer
  387.                     r.a[0] = AudioStatus.mixer;
  388.                     Execute68k(audio_data + adatCloseMixer, &r);
  389.                     AudioStatus.mixer = 0;
  390.                     return r.d[0];
  391.                 }
  392.                 AudioStatus.num_sources = 0;
  393.                 audio_exit_stream();
  394.             }
  395.             return noErr;
  396.  
  397.         // Sound component functions
  398.         case kSoundComponentInitOutputDeviceSelect:
  399.             D(bug(" InitOutputDevice\n"));
  400.             if (!audio_open)
  401.                 return noHardwareErr;
  402.             if (AudioStatus.mixer)
  403.                 return noErr;
  404.  
  405.             // Init sound component data
  406.             WriteMacInt32(audio_data + adatData + scd_flags, 0);
  407.             WriteMacInt32(audio_data + adatData + scd_format, AudioStatus.sample_size == 16 ? FOURCC('t','w','o','s') : FOURCC('r','a','w',' '));
  408.             WriteMacInt16(audio_data + adatData + scd_numChannels, AudioStatus.channels);
  409.             WriteMacInt16(audio_data + adatData + scd_sampleSize, AudioStatus.sample_size);
  410.             WriteMacInt32(audio_data + adatData + scd_sampleRate, AudioStatus.sample_rate);
  411.             WriteMacInt32(audio_data + adatData + scd_sampleCount, audio_frames_per_block);
  412.             WriteMacInt32(audio_data + adatData + scd_buffer, 0);
  413.             WriteMacInt32(audio_data + adatData + scd_reserved, 0);
  414.             WriteMacInt32(audio_data + adatStreamInfo, 0);
  415.  
  416.             // Open Apple Mixer
  417.             r.a[0] = audio_data + adatMixer;
  418.             r.d[0] = 0;
  419.             r.a[1] = audio_data + adatData;
  420.             Execute68k(audio_data + adatOpenMixer, &r);
  421.             AudioStatus.mixer = ReadMacInt32(audio_data + adatMixer);
  422.             D(bug(" OpenMixer() returns %08lx, mixer %08lx\n", r.d[0], AudioStatus.mixer));
  423.             return r.d[0];
  424.  
  425.         case kSoundComponentAddSourceSelect:
  426.             D(bug(" AddSource\n"));
  427.             AudioStatus.num_sources++;
  428.             goto delegate;
  429.  
  430.         case kSoundComponentRemoveSourceSelect:
  431.             D(bug(" RemoveSource\n"));
  432.             AudioStatus.num_sources--;
  433.             goto delegate;
  434.  
  435.         case kSoundComponentStopSourceSelect:
  436.             D(bug(" StopSource\n"));
  437.             goto delegate;
  438.  
  439.         case kSoundComponentPauseSourceSelect:
  440.             D(bug(" PauseSource\n"));
  441. delegate:    // Delegate call to Apple Mixer
  442.             D(bug(" delegating call to Apple Mixer\n"));
  443.             r.a[0] = AudioStatus.mixer;
  444.             r.a[1] = params;
  445.             Execute68k(audio_data + adatDelegateCall, &r);
  446.             D(bug(" returns %08lx\n", r.d[0]));
  447.             return r.d[0];
  448.  
  449.         case kSoundComponentStartSourceSelect:
  450.             D(bug(" StartSource\n"));
  451.             return noErr;
  452.  
  453.         case kSoundComponentGetInfoSelect:
  454.             return AudioGetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
  455.  
  456.         case kSoundComponentSetInfoSelect:
  457.             return AudioSetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
  458.  
  459.         case kSoundComponentPlaySourceBufferSelect:
  460.             D(bug(" PlaySourceBuffer\n"));
  461.             r.d[0] = ReadMacInt32(p);
  462.             r.a[0] = ReadMacInt32(p + 4);
  463.             r.a[1] = ReadMacInt32(p + 8);
  464.             r.a[2] = AudioStatus.mixer;
  465.             Execute68k(audio_data + adatPlaySourceBuffer, &r);
  466.             D(bug(" returns %08lx\n", r.d[0]));
  467.             return r.d[0];
  468.  
  469.         default:
  470.             return badComponentSelector;
  471.     }
  472. }
  473.  
  474.  
  475. /*
  476.  *  Sound input driver Open() routine
  477.  */
  478.  
  479. int16 SoundInOpen(uint32 pb, uint32 dce)
  480. {
  481.     D(bug("SoundInOpen\n"));
  482.     return noErr;
  483. }
  484.  
  485.  
  486. /*
  487.  *  Sound input driver Prime() routine
  488.  */
  489.  
  490. int16 SoundInPrime(uint32 pb, uint32 dce)
  491. {
  492.     D(bug("SoundInPrime\n"));
  493.     //!!
  494.     return paramErr;
  495. }
  496.  
  497.  
  498. /*
  499.  *  Sound input driver Control() routine
  500.  */
  501.  
  502. int16 SoundInControl(uint32 pb, uint32 dce)
  503. {
  504.     uint16 code = ReadMacInt16(pb + csCode);
  505.     D(bug("SoundInControl %d\n", code));
  506.  
  507.     if (code == 1) {
  508.         D(bug(" SoundInKillIO\n"));
  509.         //!!
  510.         return noErr;
  511.     }
  512.  
  513.     if (code != 2)
  514.         return -231;    // siUnknownInfoType
  515.  
  516.     uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
  517.     uint32 selector = param[0];
  518.     D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
  519.  
  520.     switch (selector) {
  521.         default:
  522.             return -231;    // siUnknownInfoType
  523.     }
  524. }
  525.  
  526.  
  527. /*
  528.  *  Sound input driver Status() routine
  529.  */
  530.  
  531. int16 SoundInStatus(uint32 pb, uint32 dce)
  532. {
  533.     uint16 code = ReadMacInt16(pb + csCode);
  534.     D(bug("SoundInStatus %d\n", code));
  535.     if (code != 2)
  536.         return -231;    // siUnknownInfoType
  537.  
  538.     uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
  539.     uint32 selector = param[0];
  540.     D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
  541.     switch (selector) {
  542. #if 0
  543.         case siDeviceName: {
  544.             const char *str = GetString(STR_SOUND_IN_NAME);
  545.             param[0] = 0;
  546.             memcpy((void *)param[1], str, strlen(str));
  547.             return noErr;
  548.         }
  549.  
  550.         case siDeviceIcon: {
  551.             M68kRegisters r;
  552.             static const uint16 proc[] = {
  553.                 0x558f,                    //     subq.l    #2,sp
  554.                 0xa994,                    //     CurResFile
  555.                 0x4267,                    //     clr.w    -(sp)
  556.                 0xa998,                    //     UseResFile
  557.                 0x598f,                    //     subq.l    #4,sp
  558.                 0x4879, 0x4943, 0x4e23,    //     move.l    #'ICN#',-(sp)
  559.                 0x3f3c, 0xbf76,            //     move.w    #-16522,-(sp)
  560.                 0xa9a0,                    //     GetResource
  561.                 0x245f,                    //     move.l    (sp)+,a2
  562.                 0xa998,                    //     UseResFile
  563.                 0x200a,                    //     move.l    a2,d0
  564.                 0x6604,                    //     bne        1
  565.                 0x7000,                    //  moveq    #0,d0
  566.                 M68K_RTS,
  567.                 0x2f0a,                    //1 move.l    a2,-(sp)
  568.                 0xa992,                    //  DetachResource
  569.                 0x204a,                    //  move.l    a2,a0
  570.                 0xa04a,                    //    HNoPurge
  571.                 0x7001,                    //    moveq    #1,d0
  572.                 M68K_RTS
  573.             };
  574.             Execute68k((uint32)proc, &r);
  575.             if (r.d[0]) {
  576.                 param[0] = 4;        // Length of returned data
  577.                 param[1] = r.a[2];    // Handle to icon suite
  578.                 return noErr;
  579.             } else
  580.                 return -192;        // resNotFound
  581.         }
  582. #endif
  583.         default:
  584.             return -231;    // siUnknownInfoType
  585.     }
  586. }
  587.  
  588.  
  589. /*
  590.  *  Sound input driver Close() routine
  591.  */
  592.  
  593. int16 SoundInClose(uint32 pb, uint32 dce)
  594. {
  595.     D(bug("SoundInClose\n"));
  596.     return noErr;
  597. }
  598.